﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace OrderingPlatform.MvcExtension
{
   public class StringExtension
    {
        #region 全角半角转换
        /// <summary>
        /// 转全角的函数(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToSbc(string input)
        {
            //半角转全角：
            var c = input.ToCharArray();
            for (var i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }


        /// <summary> 转半角的函数(DBC case) </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToDbc(string input)
        {
            var c = input.ToCharArray();
            for (var i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }
        #endregion

        #region 获取路径或URL
        /// <summary>
        /// 取得网站的根目录的URL
        /// </summary>
        /// <returns></returns>
        public static string GetRootUri()
        {
            var appPath = "";
            HttpContext httpCurrent = HttpContext.Current;
            if (httpCurrent != null)
            {
                var req = httpCurrent.Request;

                var urlAuthority = req.Url.GetLeftPart(UriPartial.Authority);
                if (req.ApplicationPath == null || req.ApplicationPath == "/")
                    //直接安装在   Web   站点   
                    appPath = urlAuthority;
                else
                    //安装在虚拟子目录下   
                    appPath = urlAuthority + req.ApplicationPath;
            }
            return appPath;
        }
        /// <summary>
        /// 取得网站的根目录的URL
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public static string GetRootUri(HttpRequest req)
        {
            var appPath = "";
            if (req != null)
            {
                var urlAuthority = req.Url.GetLeftPart(UriPartial.Authority);
                if (req.ApplicationPath == null || req.ApplicationPath == "/")
                    //直接安装在   Web   站点   
                    appPath = urlAuthority;
                else
                    //安装在虚拟子目录下   
                    appPath = urlAuthority + req.ApplicationPath;
            }
            return appPath;
        }
        /// <summary>
        /// 取得网站根目录的物理路径
        /// </summary>
        /// <returns></returns>
        public static string GetRootPath()
        {
            var httpCurrent = HttpContext.Current;
            string appPath = httpCurrent != null ? httpCurrent.Server.MapPath("~") : AppDomain.CurrentDomain.BaseDirectory;
            if (Regex.Match(appPath, @"\\$", RegexOptions.Compiled).Success)
                appPath = appPath.Substring(0, appPath.Length - 1);
            return appPath;
        }
        #endregion

        #region 字符串 处理
        /// <summary>
        /// 除去空格 Script 等
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static string StripHtml(string strHtml)
        {
            var strOutput = strHtml;
            var regex = new Regex(@"<[^>]+>|</[^>]+>");
            strOutput = regex.Replace(strOutput, "");
            strOutput = Regex.Replace(strOutput, "\\s*|\t|\r|\n", "");
            return strOutput;
        }

        /// <summary>
        /// 左截取
        /// </summary>
        /// <param name="inputString"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string Left(string inputString, int len)
        {
            if (inputString.Length < len)
                return inputString;
            return inputString.Substring(0, len) + "....";
        }

        /// <summary>
        /// 右截取
        /// </summary>
        /// <param name="inputString"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string Right(string inputString, int len)
        {
            return inputString.Length < len ? inputString : inputString.Substring(inputString.Length - len, len);
        }

        /// <summary>
        /// 截取指定长度字符串
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="iLength"></param>
        /// <param name="bl"></param>
        /// <returns></returns>
        public static string CutTitle(string sText, int iLength, bool bl)
        {
            if (iLength < 1) return sText;
            var b = Encoding.Default.GetBytes(sText);
            var n = 0.0;
            var m = 0;
            bool l1 = false, l2 = false;
            for (var i = 0; i < b.Length; i++)
            {
                var l0 = (b[i] > 128);
                if (l0) i++;
                n += (l0 ? 1.0 : 0.5);
                if (n > iLength)
                {
                    var strOut = (l2 ? sText.Substring(0, m - 1) : sText.Substring(0, m - 2));
                    if (Encoding.GetEncoding("GB2312").GetByteCount(strOut) + 2 > iLength * 2)
                        strOut = strOut.Substring(0, strOut.Length - 1);
                    if (bl)
                        strOut += "..";
                    return strOut;
                }
                m++;
                l2 = l1;
                l1 = l0;
            }
            return sText;
        }
        #endregion

        # region 简单的加解密方法
        /// <summary>
        /// 字符串加密
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>

        public static string Encode(string strText)
        {
            Byte[] iv64 = { 11, 22, 33, 44, 55, 66, 77, 88 };
            Byte[] byKey64 = { 10, 20, 30, 40, 50, 60, 70, 80 };
            try
            {
                var des = new DESCryptoServiceProvider();
                var inputByteArray = Encoding.UTF8.GetBytes(strText);
                var ms = new MemoryStream();
                var cs = new CryptoStream(ms, des.CreateEncryptor(byKey64, iv64), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return Convert.ToBase64String(ms.ToArray());
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 字符串解密
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>

        public static string Decode(string strText)
        {
            Byte[] iv64 = { 11, 22, 33, 44, 55, 66, 77, 88 };
            Byte[] byKey64 = { 10, 20, 30, 40, 50, 60, 70, 80 };
            try
            {
                var des = new DESCryptoServiceProvider();
                var inputByteArray = Convert.FromBase64String(strText);
                var ms = new MemoryStream();
                var cs = new CryptoStream(ms, des.CreateDecryptor(byKey64, iv64), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                var encoding = Encoding.UTF8;
                return encoding.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 使用TripleDES加密
        /// </summary>
        /// <param name="str">需要加密的字符串</param>
        /// <param name="key">16或24位密钥</param>
        /// <returns></returns>
        public static string TripleDesCrypto(string str, string key = @"]#gfV'8P""3]@xR:Z")
        {
            if (String.IsNullOrEmpty(str) || String.IsNullOrEmpty(key))
                return string.Empty;

            var data = Encoding.Unicode.GetBytes(str);
            var keys = Encoding.ASCII.GetBytes(key);

            var des = new TripleDESCryptoServiceProvider { Key = keys, Mode = CipherMode.ECB };
            ICryptoTransform cryp = des.CreateEncryptor();//加密

            return Convert.ToBase64String(cryp.TransformFinalBlock(data, 0, data.Length));
        }

        /// <summary>
        /// 使用TripleDES解密
        /// </summary>
        /// <param name="str">需要解密的字符串</param>
        /// <param name="key">16或24位密钥</param>
        /// <returns></returns>
        public static string TripleDesCryptoDe(string str, string key = @"]#gfV'8P""3]@xR:Z")
        {
            if (String.IsNullOrEmpty(str) || String.IsNullOrEmpty(key))
                return string.Empty;

            var data = Convert.FromBase64String(str);
            var keys = Encoding.ASCII.GetBytes(key);

            var des = new TripleDESCryptoServiceProvider
            {
                Key = keys,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };
            var cryp = des.CreateDecryptor();//解密

            return Encoding.Unicode.GetString(cryp.TransformFinalBlock(data, 0, data.Length));
        }

        #endregion

        #region MD5加密
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">加密字符</param>
        /// <param name="code">加密位数16/32</param>
        /// <returns></returns>
        public static string Md5(string str, int code)
        {
            var strEncrypt = string.Empty;
            if (code == 16)
            {
                var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
                if (hashPasswordForStoringInConfigFile != null)
                    strEncrypt = hashPasswordForStoringInConfigFile.Substring(8, 16);
            }

            if (code == 32)
            {
                strEncrypt = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
            }
            return strEncrypt;
        }
        #endregion

        /// <summary>
        /// 生成随机字母与数字
        /// </summary>
        /// <param name="length">生成长度</param>
        /// <returns></returns>
        public static string StrRandom(int length)
        {
            var pattern = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
            string result = "";
            int n = pattern.Length;
            var random = new Random(~unchecked((int)DateTime.Now.Ticks));
            for (int i = 0; i < length; i++)
            {
                var rnd = random.Next(0, n);
                result += pattern[rnd];
            }
            return result;
        }

        #region "获取用户IP地址"
        /// <summary>
        /// 获取用户IP地址
        /// </summary>
        /// <returns></returns>
        public static string GetIpAddress()
        {
            string userIp;
            if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
            {
                userIp = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? System.Web.HttpContext.Current.Request.UserHostAddress;
            }
            else
            {
                userIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            return userIp;
        }
        #endregion
    }
}
